/*
 * @(#)AutoTaskTemplate.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.workflow.action;

import java.sql.Connection;

import org.quartz.JobDataMap;

import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.DataSourceFactory;
import com.dcivision.framework.ErrorConstant;
import com.dcivision.framework.EventLogger;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemFunctionConstant;
import com.dcivision.framework.Utility;
import com.dcivision.workflow.WorkflowErrorConstant;
import com.dcivision.workflow.bean.WorkflowProgress;
import com.dcivision.workflow.bean.WorkflowStep;
import com.dcivision.workflow.core.AutomaticTaskInterface;
import com.dcivision.workflow.core.WorkflowProcessor;
import com.dcivision.workflow.dao.WorkflowStepDAObject;

/**
 * This is a class that acts as a template for coding automatic task. In the
 * constructor of the your automatic task, you need to define the number of
 * routine like this:
 *
 * <pre>
 * this.numOfRoutine = 2; // The automatic task will have 2 branches
 * this.labelType = LABEL_TYPE_USER_DEFINE; // Use user defined label
 * this.labelString = new String[] { &quot;common.label.yes&quot;, &quot;common.label.no&quot; }; // Get the label from ApplicationResources.properties
 * </pre>
 *
 * Inside the execute() method of the automatic task, you can get a database
 * connection by the following call:
 *
 * <pre>
 * Connection conn = null;
 * try {
 *   conn = DataSourceFactory.getConnection();
 *   SessionContainer sessionCon = this.getSessionContainer();
 * } catch (ApplicationException appEx) {
 *   log.error(appEx.getMsgCode(), appEx);
 *   throw appEx; //* prop
 * } catch (Exception e) {
 *   log.error(&quot;Error during processing this automatic task.&quot;, e);
 *   throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR); //* throw an applicationExcpetion with an appropriate
 * } finally {
 *   try {preStat.close();} catch (Exception ignore) {} finally {preStat = null;}
 *   try {conn.close();} catch (Exception ignore) {} finally {conn = null;}
 * }
 * </pre>
 *
 * Further manipulation can be acheived by obtainning the Manager/DAObject class,
 * for examples,
 *
 * <pre>
 *   WorkflowStepDAObject stepDAO = new WorkflowStepDAObject(sessionCon, conn);
 *   WorkflowStep step = (WorkflowStep) stepDAO.getObjectByID(currentProgress.getWorkflowStepID());
 * </pre>
 *
 * For some operation, you must set the UserRecord and/or the IP Address, especially
 * for those ParaDOC operations. The following code fragment demonstrate how to set
 * the default properties of a SessionContainer object:
 *
 * <pre>
 *   sessionContainer.setByPassPermission(true);
 *   sessionContainer.setUserRecord(userRecord);
 *   sessionContainer.setUserIPAddress("localhost");
 * </pre>
 *
 * @author Jenny Li
 * @company DCIVision Limited
 * @creation date 01/11/2006
 * @version $Revision: 1.12.2.4 $
 */
public class AutoTaskTemplate extends com.dcivision.workflow.core.WorkflowProcessor implements AutomaticTaskInterface {

  public static final String REVISION = "$Revision: 1.12.2.4 $";

  /** implement methods of AutomaticTaskInterface */
  public WorkflowProcessor getWorkflowProgress(){
    return new AutomaticComplete();
  }

  /** Creates a new instance of AutoTaskTemplate */
  public AutoTaskTemplate() {
    //* define how many possible exit for the current, default to 1
    this.numOfRoutine = 2;
    //* if more than one routine defined, need to set the name of each possible exit
    this.labelType = LABEL_TYPE_USER_DEFINE;
    /*
     * Warning: if numOfRoutine is unequal to the length of labelString Array.
     *          The possible exit number is the less one.
     *  For example:
     *   this is segment of the AutoLeaveTask Constructor method.
     *     this.numOfRoutine = 2;
     *     this.labelType = LABEL_TYPE_USER_DEFINE;
     *     this.labelString = new String[] {"common.label.yes", "common.label.no", "common.label.testing"};
     *   the numOfRoutine is 2,but the labelString array's length is 3.
     *   So The possible exit number of AutoLeaveTask is 2.
     */
    this.labelString = new String[] {"common.label.yes", "common.label.no"};
  }

  /*
   * following is a sample for java code of execute auto task.
   * @see com.dcivision.workflow.core.WorkflowProcessor#execute(org.quartz.JobDataMap, com.dcivision.workflow.bean.WorkflowProgress)
   */
  public synchronized void execute(JobDataMap dataMap, WorkflowProgress currentProgress) throws ApplicationException {
    log.info("***** AutoTaskTemplate workflow processor BEGIN *****");
    Connection conn = null;

    Integer trigerEventUserID = new Integer(0);
    String serverName = "127.0.0.1";
    String functionName = SystemFunctionConstant.WORKFLOW_TASK;
    String errorMessage = "";

    try {
      //* get the DB Connection
      SessionContainer sessionCon = this.getSessionContainer();

      /*************************************************************
       *  get Event Log Information Begin
       *************************************************************/
      if (!Utility.isEmpty(sessionCon.getUserRecordID())) {
        trigerEventUserID = sessionCon.getUserRecordID();
      }

      if (!Utility.isEmpty(sessionCon.getUserIPAddress())) {
        serverName = sessionCon.getUserIPAddress();
      }
      errorMessage =  " Track ID: " + currentProgress.getTrackID() +
                      ", Workflow Progress ID : " + currentProgress.getID() +
                      ", Workflow Step ID: " + currentProgress.getWorkflowStepID() +
                      "<br> ";

      /*************************************************************
       *  get Event Log Information End
       *************************************************************/
      //for schedule job useing the processer connection.
      isLocalConnection = false;
      if(!Utility.isEmpty(this.getConnection())){
        conn = this.getConnection();
      }else{
        isLocalConnection = true;
        conn = DataSourceFactory.getConnection();
      }

      //* create required DAObject
      WorkflowStepDAObject stepDAO = new WorkflowStepDAObject(sessionCon, conn);

      //* get relevant information from
      //AbstractBaseObject workflowObject = (AbstractBaseObject) dataMap.get("WORKFLOW_OBJECT");
      //log.debug("workflow object class name: "+workflowObject.getClass().getName());
      //Integer docID = workflowObject.getID();

      log.info("current progress' workflow step id: "+currentProgress.getWorkflowStepID());

      //* do what you want below
      WorkflowStep step = (WorkflowStep) stepDAO.getObjectByID(currentProgress.getWorkflowStepID());

      //* after the execution, set the desired appropriate out number
      this.returnRoutineIndex = 1; //* should be between 0 and numOfRoutine-1
      //* if need to auto-Execute the following step, set the below variable to true (default false)
      this.bAutoExecuteNextStep=false;
      //* if no need to create the child workflow progress, set the below variable to false (default true)
      this.bCreateNextWorkflowProgress=true;

      if(isLocalConnection){
        conn.commit();
      }
    } catch (ApplicationException appEx) {
      log.error("Application exception:\n"+appEx);
      /***********************************
       *  Record the Event Log.
       ***********************************/
      EventLogger.logEventMessage(trigerEventUserID, serverName, errorMessage, appEx.getMsgCode(), WorkflowErrorConstant.LOG_AUTO_TASK_ERROR_CODE, functionName, appEx.toString() );

      throw appEx; //* prop
    } catch (Exception e) {
      log.error("Error during processing this automatic task.", e);
      /***********************************
       *  Record the Event Log.
       ***********************************/
      EventLogger.logEventMessage(trigerEventUserID, serverName, errorMessage, ErrorConstant.COMMON_FATAL_ERROR, WorkflowErrorConstant.LOG_AUTO_TASK_ERROR_CODE, functionName, e.toString() );

      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR); //* throw an applicationExcpetion with an appropriate
    } finally {
      if(isLocalConnection){
        try { conn.close(); } catch (Exception ignore) {} finally { conn = null; }
      }
    }

    log.info("***** AutoTaskTemplate workflow processor END   *****");
  }



}
